SecureActionButtonTemplate
Secure Frames are Blizzard's new mechanism as of WoW 2.0 to allow for the creation of custom interfaces which may target units, cast spells, use items, and the like while ensuring that such actions are done in a way that Blizzard approves of. This is documentation for current beta functionality, and is subject to change. Creating Secure Frames All secure frames must inherit from one of the secure frame templates. These templates, found in FrameXML/SecureTemplates.xml include (but are not limited to): * SecureActionButtonTemplate - A button template for click-cast style action buttons * SecureUnitButtonTemplate - A variant of SecureActionButtonTemplate used for unit buttons ... ... * Any secure frame that does not have a UnitId will fail to perform any action that requires one for the action. myButton:SetAttribute("unit", UnitId) Frame Attribute Types After creating a frame, you will want to endow it with various attributes that determine how it reacts to user input. * You will want to set an action type for the button. This determines what action the button takes when acted upon. myButton:SetAttribute("type", ) Where typeString is one of the following base strings, which may then be modified as described below. ---- actionbar A button of this type changes your current action bar. Attributes: frame:SetAttribute("type1", "actionbar") -- Sets this frame's left click type to "actionbar" frame:SetAttribute("action1", "increment") -- Causes this frame to increment the action bar index when left clicked ----- action Executes an action. Calls UseAction(action, unit, button) Attributes: frame:SetAttribute("type1", "action") frame:SetAttribute("action1", 3) -- Causes this frame to use the action in your #3 action bar slot when left clicked frame:SetAttribute("shift-action1", 4) -- Causes this frame to use the action in your #4 action bar slot when shift-left clicked ----- pet Executes a pet action. Calls CastPetAction(self:GetAttribute("action"), self:GetAttribute("unit")) Attributes: frame:SetAttribute("type1", "pet") frame:SetAttribute("action1", 3) -- Causes this frame to use the action in your pet's #3 bar slot when left clicked frame:SetAttribute("shift-action1", 4) -- Causes this frame to use the action in your pet's #4 action bar slot when shift-left clicked ----- spell Casts a spell. Attributes: frame:SetAttribute("type1", "spell") frame:SetAttribute("spell1", "Flash Heal") frame:SetAttribute("shift-spell1", "Greater Heal") ----- item Uses an item in your inventory (equipped items) or your bags. Attributes: This causes the button to use the item in Slot #1 in your backpack when left clicked: frame:SetAttribute("type1", "item") frame:SetAttribute("bag1", "1") frame:SetAttribute("slot1", "1") This causes the button to use your Hearthstone when left clicked: frame:SetAttribute("type1", "item") frame:SetAttribute("item1", "Hearthstone") ----- macro Executes a macro. Attributes: Causes this frame to run the macro with ID #1 when left clicked. frame:SetAttribute("type1", "macro") frame:SetAttribute("macro1", 1) Note: Yes, the macro attribute takes either a Macro Name or ID - Jaycyn Causes this frame to run a macro that announces the player's target. frame:SetAttribute("type1", "macro") frame:SetAttribute("macrotext", "/party I am targetting %t") ----- stop Cancels a spell if you are targeting a spellcast. Attributes: Causes this frame to cancel spell targeting when clicked. frame:SetAttribute("type", "stop") ----- target Perform an action on the target represented by this button's unit property. * If you are targeting a spell, casts the spell on this button's unit. * If you are holding an item, attempts to drop the item onto the unit (initiate trade) * Otherwise, targets the unit. Attributes: frame:SetAttribute("type", "target") ----- focus Sets your focus to this button's unit attribute. Attributes: Clicking this frame will set your focus to this frame's specified unit. frame:SetAttribute("type", "focus") ----- assist Assist the unit specified by this button's unit attribute and attack their target. Attributes: Clicking this frame will cause you to target and start attacking the target of this button's unit. frame:SetAttribute("type", "assist") ----- click Clicks another button. Allows this button to act as a proxy to another button. Attributes: Clicking this button will call :Click() on myOtherButton. frame:SetAttribute("type", "click") frame:SetAttribute("clickbutton", myOtherButton) ----- menu Shows a popup menu. Attributes: Clicking this button will call :Click() on myOtherButton. frame:SetAttribute("type", "menu") frame.showmenu = some_function_that_shows_a_menu ---- Frame Attribute Modifications As the examples above have hinted, frame attributes may be modified to refer to allow for extreme flexibility in binding reactions to buttons. FrameXML/SecureTemplates.lua offers this documentation: The "modified attribute" takes the form of: modifier-name-button. The modifier is one of "alt-", "ctrl-", "shift-", or combination of them in this order, and the button is a number from 1 through 5 or hyphen followed custom button name mapped through some means. * Note that modifiers have to appear in order "alt-ctrl-shift-" to function, if you mess the order that attribute will only consume memory for nothing. For example, you could set an action that is used for unmodified left click like this: self:SetAttribute("action1", value); You could set an action that is used for shift-right-click like this: self:SetAttribute("shift-action2", value); You can also use a wildcard in the place of the modifier or button to denote an attribute that is used for any modifier or any button. For example, you could set an action that is used for any left click like this: self:SetAttribute("*action1", value); You could set an action that is used for shift-click with any button like this: self:SetAttribute("shift-action*", value); You can exclude an action by explicitly setting its value to ATTRIBUTE_NOOP For example, you could set an action that was used for all clicks except ctrl-left-click: self:SetAttribute("*action*", value); self:SetAttribute("shift-action1", ATTRIBUTE_NOOP); Setting the attribute by itself is equivalent to *attribute* ---- SecureActionButtons allow you to map different combinations of modifiers and buttons into actions which are executed when the button is clicked. For example, you could set up the button to respond to left clicks by targeting the focus: self:SetAttribute("unit", "focus"); self:SetAttribute("type1", "target"); You could set up all other buttons to bring up a menu like this: self:SetAttribute("type*", "menu"); self.showmenu = menufunc; SecureActionButtons are also able to perform different actions depending on whether you can attack the unit or assist the unit associated with the action button. It does so by mapping mouse buttons into "virtual buttons" based on the state of the unit. For example, you can use the following to cast "Mind Blast" on a left click and "Shadow Word: Death" on a right click if the unit can be attacked: self:SetAttribute("harmbutton1", "nuke1"); self:SetAttribute("type-nuke1", "spell"); self:SetAttribute("spell-nuke1", "Mind Blast"); self:SetAttribute("harmbutton2", "nuke2"); self:SetAttribute("type-nuke2", "spell"); self:SetAttribute("spell-nuke2", "Shadow Word: Death"); In this example, we use the special attribute "harmbutton" which is used to map a virtual button when the unit is attackable. We also have the attribute "helpbutton" which is used when the unit can be assisted. Although it may not be immediately obvious, we are able to use this new virtual button to set up very complex click behaviors on buttons. For example, we can define a new "heal" virtual button for all friendly left clicks, and then set the button to cast "Flash Heal" on an unmodified left click and "Renew" on a ctrl left click: self:SetAttribute("*helpbutton1", "heal"); self:SetAttribute("*type-heal", "spell"); self:SetAttribute("spell-heal", "Flash Heal"); self:SetAttribute("ctrl-spell-heal", "Renew"); This system is very powerful, and provides a good layer of abstraction for setting up a button's click behaviors. ---- The above, step-by-step, does the following: Creates a virtual button on this button named "nuke1", which will respond to left clicks when this unit's target is attackable. self:SetAttribute("harmbutton1", "nuke1"); Sets the virtual button "harm1"'s type to "spell" self:SetAttribute("type-nuke1", "spell"); Sets the virtual button "harm1"'s spell to "Mind Blast" self:SetAttribute("spell-nuke1", "Mind Blast"); The net result is that when you left-click the button and the button's unit is attackable, you will cast Mind Blast (if you are able). Creates a virtual button on this button named "nuke2", which will respond to right clicks when this unit's target is attackable. self:SetAttribute("harmbutton2", "nuke2"); Sets the virtual button "harm1"'s type to "spell" self:SetAttribute("type-nuke2", "spell"); Sets the virtual button "harm1"'s spell to "Mind Blast" self:SetAttribute("spell-nuke2", "Shadow Word: Death"); The net result is that when you right-click the button and the button's unit is attackable, you will cast Shadow Word:Death (if you are able). With both of these set on the button, you will be able to cast Mind Blast and SW:D by left and right clicking, respectively, while the button's unit is set to an attackable unit. We can then extend our button so that it also casts heal spells if the button's unit is friendly. self:SetAttribute("helpbutton1", "heal1"); self:SetAttribute("type-heal1", "spell"); self:SetAttribute("spell-heal1", "Flash Heal"); self:SetAttribute("helpbutton2", "heal2"); self:SetAttribute("type-heal2", "spell"); self:SetAttribute("spell-heal2", "Renew"); The net result is a button that: * Casts Mind Blast when left-clicked if your target is hostile * Casts Shadow Word: Death when right-clicked if your target is hostile * Casts Flash Heal when left-clicked if your target is friendly * Casts Renew when right-clicked if your target is friendly